package com.abel.bigwater.tlv.model

import io.netty.buffer.ByteBuf
import java.time.LocalTime

data class SignalParam(var rsrp: Int = 0,
                       var snr: Int = 0,
                       var level: Int = 0) : TlvData() {
    override fun finalLen(): Int {
        return 6
    }

    override fun fill(buf: ByteBuf): ByteBuf {
        buf.writeShort(rsrp)
        buf.writeShort(snr)
        buf.writeShort(level)

        return buf
    }

    override fun parse(buf: ByteBuf): ByteBuf {
        rsrp = buf.readShort().toInt() and 0xFFFF
        snr = buf.readShort().toInt() and 0xFFFF
        level = buf.readShort().toInt() and 0xFFFF

        return buf
    }
}

data class TlvData2Realtime(
        var reading: Long = 0,
        var dayForward: Long = 0,
        var dayRevert: Long = 0,
        var maxFlow: Int = 0,
        var timestamp: LocalTime? = null,
        var signal: SignalParam? = null,
        var volt: Int = 0,
        var pulse: Int = 1) : TlvData(RealtimeParam.TAG) {

    override fun fill(buf: ByteBuf): ByteBuf {
        if (length == 0) finalLen()

        with(buf.alloc().buffer()) {
            writeByte(tag.toInt())
            writeShort(length)

            writeByte(RealtimeParam.T0RealTotal.id.toInt())
            writeInt(reading.toInt())

            writeByte(RealtimeParam.T1DayTotal.id.toInt())
            writeInt(dayForward.toInt())

            writeByte(RealtimeParam.T2DayRevertTotal.id.toInt())
            writeInt(dayRevert.toInt())

            writeByte(RealtimeParam.T3DayMaxFlow.id.toInt())
            writeShort(maxFlow)

            writeByte(RealtimeParam.T4DayMaxTime.id.toInt())
            writeBytes(TlvHelper.toByteArray(timestamp!!))

            writeByte(RealtimeParam.T5Signal.id.toInt())
            signal!!.fill(buf)

            writeByte(RealtimeParam.T6Volt.id.toInt())
            buf.writeShort(volt)

            writeByte(RealtimeParam.T7Pulse.id.toInt())
            buf.writeShort(pulse)

            buf.writeBytes(this)
        }

        return buf
    }

    override fun parse(buf: ByteBuf): ByteBuf {
        try {
            super.parse(buf)
        } catch (ex: Exception) {
            log.error("FAIL to parse caused by ${ex.message}", ex)
        }

        for (p1 in pieceList.orEmpty()) {
            when (p1.id) {
                RealtimeParam.T0RealTotal.id -> reading = p1.readInt()
                RealtimeParam.T1DayTotal.id -> dayForward = p1.readInt()
                RealtimeParam.T2DayRevertTotal.id -> dayRevert = p1.readInt()
                RealtimeParam.T3DayMaxFlow.id -> maxFlow = p1.readShort()
                RealtimeParam.T4DayMaxTime.id -> timestamp = TlvHelper.toLocalTime(p1.value!!)
                RealtimeParam.T5Signal.id -> {
                    signal = signal ?: SignalParam()
                    signal!!.parse(buf.alloc().buffer().writeBytes(p1.value!!))
                }
                RealtimeParam.T6Volt.id -> volt = p1.readShort()
                RealtimeParam.T7Pulse.id -> pulse = p1.readShort()
            }
        }

        return buf
    }
}